﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.Specialized;
using System.Web;
using Transcend.DP3.Helper;
using System.Web.SessionState;
using System.Collections;
using System.Text.RegularExpressions;
using Transcend.DP3.Db;

namespace Transcend.DP3.Helper
{

	public class HttpContextExprEvalutor
	{

		public HttpContextExprEvalutor(HttpContext context)
		{
			this.context = context;
		}

		private readonly HttpContext context;
		/// <summary>
		/// 参数模式正则
		/// </summary>
		private static readonly string ExprPattern = "((param|request|form|querystring|session|application|cookie|server|header)\\([\"']([^\"]+)[\"']\\))";
		/// <summary>
		/// 参数模式匹配正则
		/// </summary>
		private static readonly Regex WebContextParamExprRegex = new Regex(ExprPattern, RegexOptions.Multiline | RegexOptions.IgnoreCase);
		
		/// <summary>
		/// 计算单个表达式值
		/// </summary>
		/// <param name="context"></param>
		/// <param name="valueExpr"></param>
		/// <returns></returns>
		public static object EvalExpr(HttpContext context, string scope, string [] part)
		{

			// 拆分参数占位符
			object val = null;
			string pName = string.Join(".", part, 0, Math.Max(part.Length - 1, 1));
			switch (scope.ToLower())
			{
				// 取参数，包括form和QueryString
				case "request":
				case "param":
					val = context.Request[pName];
					break;
				// 取form表单参数
				case "form":
					val = context.Request.Form[pName];
					break;
				// 取querystring参数
				case "querystring":
					val = context.Request.QueryString[pName];
					break;
				// 取保存到会话的信息
				case "session":
					val = ONHelper.PropertyValue(context.Session, part, 0);
					break;
				// 取保存到应用程序的对象信息
				case "application":
					val = ONHelper.PropertyValue(context.Application, part, 0);
					break;
				// 取cookie信息
				case "cookie":
					val = CookieValue(context.Request.Cookies, pName);
					break;
				// 取服务器变量信息
				case "server":
					val = context.Request.ServerVariables[pName];
					break;
				// 取http请求头信息
				case "header":
					val = context.Request.Headers[pName];
					break;
				default:
					ExHelper.InvalidOperation(string.Format("取值表达式{0}[{1}]不受支持", pName, string.Join(".", part)));
					break;
			}

			return val;
		}

		/// <summary>
		/// 获取cookie的值
		/// </summary>
		/// <param name="cookieCol"></param>
		/// <param name="name"></param>
		/// <returns></returns>
		private static string CookieValue(HttpCookieCollection cookieCol, string name)
		{
			if (cookieCol == null) return null;
			var ck = cookieCol.Get(name);
			if (ck == null) return null;
			return ck.Value;
		}

		/// <summary>
		/// 解析字符串中的表达式并计算出表达式的值
		/// </summary>
		/// <param name="context"></param>
		/// <param name="source">字符串</param>
		/// <param name="isRestrict">是否启用严格检查模式，如果表达式值计算为空，将抛出异常</param>
		/// <returns></returns>
		public static string EvalString(HttpContext context, string source, bool isRestrict)
		{

			string ret = source;
			string scope = null;
			string expr = null;
			object value = null;
			MatchCollection mc = WebContextParamExprRegex.Matches(source);

			foreach (Match m in mc)
			{
				if (m.Groups.Count == 4)
				{
					scope = m.Groups[2].Value;
					expr = m.Groups[3].Value;
					value = EvalExpr(context, scope, expr.Split(new char[]{ '.' }));
					if (isRestrict && value == null)
					{
						ExHelper.InvalidOperation(string.Format("表达式{0}缺少值", m.Value));
					}
					else
					{
						if (value == null) value = string.Empty;
					}

					ret = ret.Replace(m.Value, value.ToString());
				}
				else
				{
					ExHelper.InvalidOperation(string.Format("非法的表达式{0}", m.Value));
				}
			}

			return ret;
		}

	}
}
